package bin_tree.heap.leetcode;

import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Queue;

/**
 * 最小的K个数，取小用大
 * @author yuisama
 * @date 2022/03/02 21:40
 **/
public class Num17_14_SmallestK {
    public int[] smallestK(int[] arr, int k) {
        if (arr.length == 0 || k == 0) {
            return new int[0];
        }
        // 构造一个最大堆,JDK默认是最小堆，使用比较器改造为最大堆
        // 要把最小堆改为最大堆，就是要告诉编译器值越大，让编译器看来他反而小
        Queue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        // 扫描原数组，优先级队列中只存储k个值
        for (int i : arr) {
            if (queue.size() < k) {
                queue.offer(i);
            }else {
                // 当前判断扫描元素和堆顶元素的关系
                // 若扫描元素 > 堆顶元素 > 堆中的所有值，这个值一定不是我要找的数
                int peek = queue.peek();
                if (i > peek) {
                    continue;
                }else {
                    // 此时当前元素  < 堆顶元素，将堆顶元素出队，将较小值i入队
                    queue.poll();
                    queue.offer(i);
                }
            }
        }
        // 此时最大堆中就保存了最小的k个数
        int[] ret = new int[k];
        for (int i = 0; i < k; i++) {
            ret[i] = queue.poll();
        }
        return ret;
    }
}